package org.itec.yeast.service;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.itec.yeast.db.DataManager;
import org.itec.yeast.trdo.TRCorrelationResult;
import org.itec.yeast.trdo.TRInteractionResult;

public class GeneSearch extends HttpServlet {
	private static final String SQL_INTERACTION_QUERY = "SELECT g1.Standard_Gene_Name, g1.Alias, g1.Description, g2.Standard_Gene_Name, g2.Alias, g2.Description, s1.Strain_Name, s2.Strain_Name, s1.Marker_Type, i.Interaction_Score, i.P_Value FROM gene g1 LEFT JOIN (gene g2, strain s1, strain s2, interaction i) ON s1.GENE_idGENE = g1.idGENE AND i.Query_Strain = s1.idSTRAIN AND s2.idSTRAIN = i.Array_Strain AND g2.idGENE = s2.GENE_idGENE WHERE g1.Standard_Gene_Name in (";
	private static final String SQL_INTERACTION_ARRAY = "SELECT g1.Standard_Gene_Name, g1.Alias, g1.Description, g2.Standard_Gene_Name, g2.Alias, g2.Description, s1.Strain_Name, s2.Strain_Name, s1.Marker_Type, i.Interaction_Score, i.P_Value FROM gene g1 LEFT JOIN (gene g2, strain s1, strain s2, interaction i) ON s1.GENE_idGENE = g1.idGENE AND i.Query_Strain = s1.idSTRAIN AND s2.idSTRAIN = i.Array_Strain AND g2.idGENE = s2.GENE_idGENE WHERE g2.Standard_Gene_Name in (";
	private static final String SQL_CORRELATION_STRAIN1 = "SELECT g1.Standard_Gene_Name, g1.Alias, g1.Description, g2.Standard_Gene_Name, g2.Alias, g2.Description, s1.Strain_Name, s2.Strain_Name, c.Correlation_Score FROM gene g1 LEFT JOIN (gene g2, strain s1, strain s2, correlation c) ON s1.GENE_idGENE = g1.idGENE AND c.Strain1 = s1.idSTRAIN AND s2.idSTRAIN = c.Strain2 AND g2.idGENE = s2.GENE_idGENE WHERE g1.Standard_Gene_Name in (";
	private static final String SQL_CORRELATION_STRAIN2 = "SELECT g1.Standard_Gene_Name, g1.Alias, g1.Description, g2.Standard_Gene_Name, g2.Alias, g2.Description, s1.Strain_Name, s2.Strain_Name, c.Correlation_Score FROM gene g1 LEFT JOIN (gene g2, strain s1, strain s2, correlation c) ON s1.GENE_idGENE = g1.idGENE AND c.Strain1 = s1.idSTRAIN AND s2.idSTRAIN = c.Strain2 AND g2.idGENE = s2.GENE_idGENE WHERE g2.Standard_Gene_Name in (";
	private static final String SQL_INTERACTION_VALUE_NEGATIVE = " AND i.Interaction_Score < ? AND i.P_Value < ?";
	private static final String SQL_INTERACTION_VALUE_POSITIVE = " AND i.Interaction_Score > ? AND i.P_Value < ?";
	
	
	/**
	 * Constructor of the object.
	 */
	public GeneSearch() {
		super();
	}

	/**
	 * Destruction of the servlet. <br>
	 */
	public void destroy() {
		super.destroy();
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");
		request.setCharacterEncoding("utf-8");
		String[] genes = request.getParameter("geneNames").split(" ");
		double epsilonNeg = request.getParameter("e_neg") == null ? 0 : Double.parseDouble(request.getParameter("e_neg"));
		double pvalueNeg = request.getParameter("p_neg") == null ? 1 : Double.parseDouble(request.getParameter("p_neg"));
		double epsilonPos = request.getParameter("e_pos") == null ? 0 : Double.parseDouble(request.getParameter("e_pos"));
		double pvaluePos = request.getParameter("p_pos") == null ? 1 : Double.parseDouble(request.getParameter("p_pos"));
		String rValue = request.getParameter("rvalue");
		
		
		String interacitonQuery = this.SQL_INTERACTION_QUERY;
		String interacitonArray = this.SQL_INTERACTION_ARRAY;
		String correlationStrain1 = this.SQL_CORRELATION_STRAIN1;
		String correlationStrain2 = this.SQL_CORRELATION_STRAIN2;
		String interactionNegative = "";
		String interactionPositive = "";
		String correlation = "";
		
		
		for (int i = 0; i < genes.length; i++){
			interacitonQuery += ("'" + genes[i] + "', ");
			interacitonArray += ("'" + genes[i] + "', ");
			correlationStrain1 += ("'" + genes[i] + "', ");
			correlationStrain2 += ("'" + genes[i] + "', ");
		}
		
		interacitonQuery = interacitonQuery.substring(0, interacitonQuery.length() - 2);
		interacitonArray = interacitonArray.substring(0, interacitonArray.length() - 2);
		correlationStrain1 = correlationStrain1.substring(0, correlationStrain1.length() - 2);
		correlationStrain2 = correlationStrain2.substring(0, correlationStrain2.length() - 2);
		interacitonQuery += ")";
		interacitonArray += ")";
		correlationStrain1 += ")";
		correlationStrain2 += ")";
		
		interactionNegative = "(" + interacitonQuery + this.SQL_INTERACTION_VALUE_NEGATIVE + ") UNION ALL (" + interacitonArray + this.SQL_INTERACTION_VALUE_NEGATIVE + ")  ORDER BY Interaction_Score ASC";
		interactionPositive = "(" + interacitonQuery + this.SQL_INTERACTION_VALUE_POSITIVE + ") UNION ALL (" + interacitonArray + this.SQL_INTERACTION_VALUE_POSITIVE + ")  ORDER BY Interaction_Score DESC";
		
		if (rValue.equals("significant")){
			correlation = "(" + correlationStrain1 + " AND (c.Correlation_Score > 0.1 OR c.Correlation_Score < -0.1)) UNION ALL (" + correlationStrain2 + " AND (c.Correlation_Score > 0.1 OR c.Correlation_Score < -0.1))";
		}
		correlation += " ORDER BY Correlation_Score DESC";
		
		List interactionNegativeList = DataManager.queryBySql(TRInteractionResult.class, interactionNegative, new Object[]{epsilonNeg, pvalueNeg, epsilonNeg, pvalueNeg});
		List interactionPositiveList = DataManager.queryBySql(TRInteractionResult.class, interactionPositive, new Object[]{epsilonPos, pvaluePos, epsilonPos, pvaluePos});
		List correlationList = DataManager.queryBySql(TRCorrelationResult.class, correlation, null);
		
		request.setAttribute("interactionNegativeCount", interactionNegativeList.size());
		request.setAttribute("interactionPositiveCount", interactionPositiveList.size());
		request.setAttribute("correlationCount", correlationList.size());
		request.setAttribute("interactionNegativeList", interactionNegativeList);
		request.setAttribute("interactionPositiveList", interactionPositiveList);
		request.setAttribute("correlationList", correlationList);
		request.getRequestDispatcher("searchresult.jsp").forward(request, response);
	}

	public void init() throws ServletException {
	}
}
